//
// onload.js
// vue3-element-admin
//
// Created by 区区电脑 on 2023/04/10.
//

import "nprogress/nprogress.css";
import "./styles/element/index.scss";
import ElementPlus from "element-plus";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import {ElMessage, ElNotification, ElMessageBox, ElLoading} from "element-plus";
import registerCustomComponents from "./components";
import log from "@/utils/log.js";
import workbenches from "@business/workbenches.vue"
import VxeUI from 'vxe-pc-ui'
import 'vxe-pc-ui/lib/style.css'
import VxeTable from 'vxe-table'
import 'vxe-table/lib/style.css'
import {hasPermission, adminHasPermission, hasPagePermission, adminHasPagePermission} from "./utils/permission";
import registerVBinds from "./utils/vbinds.js";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import 'dayjs/locale/en.js';
import LocalizedFormat from "dayjs/plugin/localizedFormat"
import md5 from "js-md5";
import lodash from "lodash";
import LocalDB from "./utils/LocalDB.js"
import * as api from "./api.js"
import utc from "dayjs/plugin/utc"
import timezone from "dayjs/plugin/timezone"
import $signalr from "./signalr.js"
import * as echarts from "echarts";
import {chooseFile} from "@/utils/utils.js"
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import "animate.css/animate.min.css"
import Wow from "wow.js"
import "viewerjs/dist/viewer.min.css"
import store from "./store/index.js"


// dayjs 本地化
// dayjs.locale('zh-cn');
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.tz.setDefault("Asia/Shanghai")
dayjs.extend(LocalizedFormat)
VxeTable.setConfig({
    modal: {
        position: {
            top: 40
        }
    }
})

export default function onload(app) {

    window.$Wow = Wow
    // 配置彩色log
    log(app);
    // 配置全局根程序
    window.$app = app;
    // 安装 element-plus ui 库
    app.use(ElementPlus, {
        locale: zhCn,
    });
    // 安装 element-plus icon 库
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component)
    }
    // 全局 echarts 库
    window.$echarts = echarts;
    // 安装 vxe-table
    app.use(VxeUI);
    app.use(VxeTable);
    // 全局 dayjs 日期库
    window.$dayjs = dayjs;
    // 全局 MD5 算法
    window.$md5 = md5;
    // 全局 lodash
    window.$lodash = lodash;
    // 复制到粘贴板
    window.$copyText = copyText;
    // 全局 permission 判断
    window.$hasPermission = hasPermission;
    // 全局 adminPermission 判断
    window.$adminHasPermission = adminHasPermission;
    // 全局 hasPagePermission 判断
    window.$hasPagePermission = hasPagePermission;
    // 全局 adminHasPagePermission 判断
    window.$adminHasPagePermission = adminHasPagePermission;

    // 获取地址栏参数
    window.$getQueryParam = (name) => {
        const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        const r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    }
    // 睡眠
    window.$sleep = (value = 0) => {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve()
            }, value)
        })
    }

    setLayoutType()
    // 全局 message
    window.$message = {
        success: message => {
            ElMessage({type: "success", message});
        },
        warn: message => {
            ElMessage({type: "warning", message});
        },
        warning: message => {
            ElMessage({type: "warning", message});
        },
        error: message => {
            ElMessage({type: "error", message});
        },
    };
    // 全局 notification
    window.$notification = {
        success: (title, message) => {
            ElNotification({type: "success", title, message});
        },
        warn: (title, message) => {
            ElNotification({type: "warning", title, message});
        },
        warning: (title, message) => {
            ElNotification({type: "warning", title, message});
        },
        error: (title, message) => {
            ElNotification({type: "error", title, message});
        },
        custom: (title, message, icon) => {
            return ElNotification({title, message, icon, dangerouslyUseHTMLString: true});
        }
    }
    // 全局confirm
    window.$confirm = (title, message, callback) => {
        ElMessageBox.confirm(message, title, {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            "confirmButtonClass": "danger-confirm"
        }).then(() => {
            callback && callback(true)
        }).catch(() => {
            callback && callback(false)
        })
    }
    // 全局confirm 同步
    window.$confirmSync = (title, message) => {
        return new Promise(resolve => {
            ElMessageBox.confirm(message, title, {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                "confirmButtonClass": "danger-confirm"
            }).then(() => {
                resolve(true)
            }).catch(() => {
                resolve(false)
            })
        })

    }
    // 全局 alert
    window.$alert = (title, message, callback) => {
        ElMessageBox.alert(message, title, {
            confirmButtonText: '确定',
            callback
        })
    }
    // 全局 loading
    window.$loading = (message, timer) => {
        const loading = ElLoading.service({
            text: message
        })
        if (timer) {
            setTimeout(() => loading.close(), timer)
        }
        return loading
    }
    // 全局选择文件
    window.$chooseFile = chooseFile;
    // 全局 文件全路径
    window.$fileFullPath = (val = "") => {
        if (!val) return ""
        return val.indexOf("http") > -1 ? val : window.$config.baseUrl + "/" + val
    };
    // 全局处理桩号格式化显示
    window.$locationNum = (value) => {
        let numA = 0;
        let numB = 0;
        if (value !== null && value !== undefined) {
            // 桩号以: KnumA+numB 形式
            numA = parseInt(value)
            // 这一步必须这样处理,否则会有js 精度问题
            const b = parseFloat(value - numA).toFixed(3);
            numB = parseInt(b * 1000);
        }
        return `K${numA}+${numB}`
    }
    // 全局处理格式化
    window.$format = {
        dateTime(val, format = "YYYY-MM-DD HH:mm:ss") {
            if (!val) return "";
            return $dayjs(val).format(format);
        },
        fullPath(path) {
            return `${$config.baseUrl}/${path}`
        },
        fileSize(size) {
            if (!size) return "";
            if (size <= 1024) return "1kb"
            if (size > 1024 && size < 1024 * 1024) return parseFloat((size / 1024).toFixed(3)) + " kb"
            if (size >= 1024 * 1024 && size < 1024 * 1024 * 1024) return parseFloat((size / 1024 / 1024).toFixed(3)) + " Mb"
            if (size >= 1024 * 1024 * 1024 && size < 1024 * 1024 * 1024 * 1024) return parseFloat((size / 1024 / 1024 / 1024).toFixed(3)) + " G"
        }
    }
    // 全局判断至少有一个条件成立
    window.$hasOneOk = (source, targets = []) => {
        return targets.filter(target => target === source).length > 0
    }
    // 批量注册自定义组件
    app.use(registerCustomComponents);
    // 注册自定义指令
    registerVBinds(app);
    // 单独注册工作台
    app.component("workbenches", workbenches)
    // 初始化全局字典
    initSystemDict(app)
    // 挂载 signalr
    window.$signalr = $signalr;
    // 动态表格固定列
    window.$fixedColumn = (pos) => {
        if (store.getters.layoutType === "pc") {
            return pos
        }
        return ""
    };
    // 动态表格固定列宽度
    window.$widthColumn = (value) => {
        if (store.getters.layoutType === "pc") {
            return value
        }
        return 80
    }

    // 低响应的窗口尺寸变化
    window.$addLowResize = (callback) => {
        let timer;
        window.addEventListener("resize", () => {
            if (timer) {
                clearTimeout(timer)
                timer = null
            }
            timer = setTimeout(() => {
                const frame = {
                    width: document.documentElement.clientWidth,
                    height: document.documentElement.clientHeight
                }
                callback && callback(frame)
                clearTimeout(timer)
                timer = null
            }, 100)

        })
    }
    /**
     * 下载文件
     * @param url
     * @param fileName
     */
    window.$downloadFile = (url, fileName) => {
        const link = document.createElement('a');
        link.href = url;
        link.download = fileName;
        link.target = "_blank"; // 可选，如果希望在新窗口中下载文件，请取消注释此行
        link.click();
    }

    /**
     * 使用定时器等待指定条件
     * @param isOk 属性值判断为 true 的条件回调
     * @param callback 有值后触发
     * @param timeout 多长时间检查一次（毫秒）
     */
    window.$waitingIsOk = (isOk, callback, timeout = 1000) => {
        if (isOk()) callback && callback()
        const interval = setInterval(() => {
            if (isOk()) {
                callback && callback();
                clearInterval(interval);
            }
        }, timeout)
    }
}

// 全局copy
function copyText(text) {
    const textareaC = document.createElement('textarea');
    textareaC.setAttribute('readonly', 'readonly'); //设置只读属性防止手机上弹出软键盘
    textareaC.value = text;
    document.body.appendChild(textareaC); //将textarea添加为body子元素
    textareaC.select();
    document.execCommand('copy');
    document.body.removeChild(textareaC);//移除DOM元素
    window.$message.success("已复制到粘贴板")
}

// 初始化系统字典
function initSystemDict(app) {
    // 获取字典列表 通过字典类型编号
    window.$getDictDataListWithTypeCode = (typeCode) => {
        const localDict = LocalDB.getItem("dict_cache");
        const dictData = localDict.data ?? [];
        const dict = dictData.find((t) => t.code === typeCode) ?? {};
        return dict.children ?? [];
    };
    // 获取字典数据详情 通过字典类型编号和字典数据编号
    window.$getDictDataInfoWithTypeCodeAndDataCode = (typeCode, dataCode) => {
        const localDict = LocalDB.getItem("dict_cache");
        const dictData = localDict.data ?? [];
        const dict = dictData.find((t) => t.code === typeCode) || {};
        return (dict.children ?? []).find(t => t.code === dataCode) || {};
    };
    // 获取字典数据值 通过字典类型编号和字典数据编号
    window.$getDictDataValueWithTypeCodeAndDataCode = (typeCode, dataCode) => {
        const localDict = LocalDB.getItem("dict_cache");
        const dictData = localDict.data ?? [];
        const dict = dictData.find((t) => t.code === typeCode) || {};
        const data = (dict.children ?? []).find(t => t.code === dataCode) || {};
        return data.name;
    };
    api.GetDictTree().then(({success, data}) => {
        if (!success) return;
        // console.log("系统字典: ", data);
        LocalDB.setItem("dict_cache", data)
    });
}

/**
 * 设置布局类型
 */
function setLayoutType() {
    const width = document.documentElement.clientWidth;
    if (width >= 750) {
        store.dispatch("setLayoutType", "pc")
    } else {
        store.dispatch("setLayoutType", "mobile")
    }
    window.addEventListener("resize", () => {
        const width = document.documentElement.clientWidth;
        if (width >= 750) {
            store.dispatch("setLayoutType", "pc")
        } else {
            store.dispatch("setLayoutType", "mobile")
        }
    })
}
